//`timescale 1ns / 1ps
module Async_port(
/*********NAND flash Async mode Port*********/
    output  wire    WE_s,  
    output  wire    RE_s,   
    output  reg    CLE,    
    output  reg    ALE,  

    input  wire[7:0] DQ_i,
    output reg[7:0]  DQ_o,
    output     wire  DQ_oen,

/***********Mode control port**************/
    input   wire        clkX2,
    input   wire        dclk,
    input   wire        rst_n,
    input   wire[2:0]   Cmd,  //
    input   wire[7:0]   InputVal,       //
    output  wire        IV_En,
    output  reg[7:0]    ReadVal,
    output  wire         RV_En
);

parameter State_command =   3'b000;
parameter State_adderss =   3'b001;
parameter State_WriteData = 3'b010;
parameter State_ReadData  = 3'b011;
parameter State_Idle =      3'b100;
parameter State_WriteWait = 3'b111;

parameter Idle =      4'b1111;
parameter WriteWait = 4'b0000;
parameter Command =   4'b0001;
parameter WriteData = 4'b0010;
parameter ReadData =  4'b0100;
parameter Address =   4'b1000;

reg[2:0] cur_state;
reg we_en;
reg re_en;
reg rv_en;


assign RV_En = rv_en ? dclk : 0;
assign DQ_oen = we_en;
assign WE_s = we_en ? dclk : 1'b1;
assign RE_s =  re_en ? dclk : 1'b1;
assign IV_En = dclk ;

always @(negedge dclk or negedge rst_n) begin
    if (!rst_n) begin
        CLE <= 0;
        ALE <= 0;
    end else begin
        if (Cmd == State_command) begin
            CLE <= 1;
        end else begin
            CLE <= 0;
        end
        if (Cmd == State_adderss) begin
            ALE <= 1;
        end else begin
            ALE <= 0;
        end
    end
end

always @(negedge dclk) begin
    if (Cmd == State_adderss || Cmd == State_command || Cmd == State_WriteData || Cmd == WriteWait) begin
        DQ_o <= InputVal;
        we_en <= 1;
    end else if (Cmd == State_ReadData) begin
        we_en <= 0;
    end else begin
        DQ_o <= DQ_o;
        we_en <= 0;             
    end
end

always @(negedge dclk) begin
    if (Cmd == State_ReadData) begin
        re_en <= 1;
    end else begin
        re_en <= 0;
    end
end

//reg read_start;
always @(posedge dclk or negedge rst_n) begin
    if (!rst_n) begin
        ReadVal <= 0;
        rv_en <= 0;
      //  read_start <= 1'b0;
    end else begin
        if (Cmd == State_ReadData) begin
            ReadVal <= DQ_i;
         //   if (read_start == 1) begin
                rv_en <= 1'b1;
          //      read_start <= read_start;
         //   end else begin
         //       rv_en <= rv_en;
        //        read_start <= 1;
         //   end
        end else begin
            ReadVal <= 0;
            rv_en <= 1'b0;
        //    read_start <= 1'b0;
        end 
    end
    
end
/*
always @(negedge clkX2 or negedge rst_n) begin
    if (rst_n) begin//  
        if (read_start == 1'b1 && Cmd == State_ReadData) begin
            RV_En <= 1'b1;
        end else begin
            RV_En <= 1'b1;
        end
        
    end else begin
        RV_En <= 1'b0;
    end
end
*/
endmodule // Async_port